package com.inspur.dgov.bsp.application.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.inspur.dgov.bsp.application.entity.PubResource;
import com.inspur.dgov.bsp.application.service.PubResourceService;
import com.inspur.dgov.bsp.application.service.TreeService;
import com.inspur.dgov.bsp.application.vo.ResourceVO;
import com.inspur.dgov.common.secure.dto.SecureUser;
import com.inspur.dgov.common.secure.utils.SecureUtil;
import com.inspur.dgov.common.tool.api.R;
import com.inspur.dgov.common.tool.constant.AppConstant;
import com.inspur.dgov.common.tool.node.TreeNode;
import com.inspur.dgov.common.tool.node.TreeNodeUtil;
import com.inspur.dgov.common.tool.utils.UniqueIdGenerator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 菜单按钮资源控制器
 *
 * @Author chiyupei
 * @Date 20/3/17 下午10:38
 * @Version 1.0
 * @Description 菜单按钮资源控制器
 */
@RestController
@RequestMapping("/resource")
@Api(value = "菜单按钮资源", tags = "菜单按钮资源")
public class PubResourceController {

    @Value("${app.default.id}")
    private String defaultAppId;

    @Value("${tenant.default.id}")
    private String defaultTenantId;

    @Autowired
    private PubResourceService pubResourceService;

    @Autowired
    private TreeService treeService;

    /**
     * 前端菜单数据
     */
    @GetMapping("/menus")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "appId", value = "应用ID", paramType = "query", dataType = "String")
    })
    @ApiOperation(value = "前端菜单数据", notes = "前端菜单数据", position = 1)
    public R<List<ResourceVO>> menus(@RequestParam(value = "appId", required = false) String appId) {
        List<ResourceVO> list = new ArrayList<>();
        if (StrUtil.isBlank(appId)) {
            appId = this.defaultAppId;
        }
        //根据用户角色获取菜单资源
        SecureUser user = SecureUtil.getUser();
        String roleId = user.getRoleId();
        list = this.pubResourceService.menus(roleId, appId);
        return R.data(TreeNodeUtil.merge(list));
    }

    /**
     * 资源分页列表
     *
     * @param query
     * @param page
     * @return
     */
    @PostMapping("/page")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "资源编码", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "name", value = "资源名称", paramType = "query", dataType = "string")
    })
    @ApiOperation(value = "资源信息列表", notes = "传入资源编码或资源名称", position = 2)
    public R<IPage<ResourceVO>> page(@ApiIgnore @RequestParam Map<String, Object> query, Page page) {
        Object appId = query.get("appId");
        if (null == appId || StrUtil.isBlank(appId.toString())) {
            query.put("appId", this.defaultAppId);
        }

        IPage<ResourceVO> pages = this.pubResourceService.selectResourcePage(page, query);
        return R.data(pages);
    }

    /**
     * 父级资源
     */
    @GetMapping("/parent")
    @ApiOperation(value = "查询父级资源", notes = "传入应用ID", position = 3)
    public R<List<TreeNode>> parent(@RequestParam(value = "appId", required = false) String appId) {
        List<TreeNode> tree = new ArrayList<>();
        Map<String, Object> param = new HashMap<>();
        if (StrUtil.isBlank(appId)) {
            param.put("appId", this.defaultAppId);
        }
        tree.addAll(this.treeService.resourceParent(param));
        return R.data(TreeNodeUtil.merge(tree));
    }

    /**
     * 新增资源
     *
     * @param resource
     * @return
     */
    @PostMapping("/add")
    @ApiOperation(value = "新增资源", notes = "传入资源信息", position = 4)
    public R add(@RequestBody PubResource resource) {
        SecureUser curUser = SecureUtil.getUser();
        LocalDateTime now = LocalDateTime.now();
        Long id = UniqueIdGenerator.generateId();
        resource.setId(id);
        resource.setCreator(Long.valueOf(curUser.getUserId()));
        resource.setCreateTime(now);
        resource.setStatus(AppConstant.DB_STATUS_NORMAL);
        if (null == resource.getAppId()) {
            resource.setAppId(Long.valueOf(this.defaultAppId));
        }
        boolean ret = this.pubResourceService.save(resource);
        return R.status(ret);
    }

    /**
     * 更新资源
     *
     * @param resource
     * @return
     */
    @PostMapping("/update")
    @ApiOperation(value = "更新资源", notes = "传入资源信息", position = 5)
    public R update(@RequestBody PubResource resource) {
        SecureUser curUser = SecureUtil.getUser();
        LocalDateTime now = LocalDateTime.now();
        resource.setUpdator(Long.valueOf(curUser.getUserId()));
        resource.setUpdateTime(now);
        boolean ret = this.pubResourceService.updateById(resource);
        return R.status(ret);
    }

    /**
     * 删除资源
     */
    @PostMapping("/remove")
    @ApiOperation(value = "删除资源", notes = "传入资源信息", position = 6)
    public R remove(@RequestBody PubResource resource) {
        //检查是否有下级
        QueryWrapper<PubResource> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PubResource::getParentId, resource.getId());
        int count = this.pubResourceService.count(queryWrapper);
        if (count > 0) {
            return R.fail("存在下级资源，不能删除");
        }
        //TODO 删除角色资源关系
        boolean ret = this.pubResourceService.removeById(resource);
        return R.status(ret);
    }

    /**
     * 获取权限分配资源
     */
    @GetMapping("/grantResource")
    @ApiOperation(value = "权限分配树形结构", notes = "权限分配树形结构")
    public R<List<TreeNode>> grantResource() {
        SecureUser curUser = SecureUtil.getUser();
        String tenantId = curUser.getTenantId();
        List<TreeNode> tree;
        if (StrUtil.equals(this.defaultTenantId, tenantId)) {
            tree = this.treeService.grantResource();
        } else {
            tree = this.treeService.grantResourceByRole(StrUtil.split(curUser.getRoleId(), ','));
        }
        return R.data(TreeNodeUtil.merge(tree));
    }
}
